﻿
namespace Mulala.Cavan.Application.MainBoundedContext.SecurityModule
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Security.Principal;
    using System.Threading;
    using System.Web;
    using Spring.Context;
    using Spring.Context.Support;
    using Mulala.Cavan.Domain.MainBoundedContext.SecurityModule;
    using Mulala.Cavan.Core.Extension;
    using Mulala.Cavan.Domain.MainBoundedContext.SearchModule;
    using Mulala.Cavan.Core.Message;

    public class CurrentUserProvider 
    {
        const string Viewer = "游客";

        public CurrentUserProvider()
        {
            Init();
        }

        public virtual UserAccount UserAccount
        {
            get { return GetUserAccount(); }
        }


        #region protected User
        protected virtual UserAccount GetUserAccount()
        {
            if (Identity.IsAuthenticated)
            {
                var userAccount = HttpContext.Current.Items[GetType().FullName + "UserAccount"] as UserAccount; // is cached for this request
                if (userAccount.IsNull())
                {
                    UserAccountSearch userAccountSearch = new UserAccountSearch();
                    userAccountSearch.Name = Identity.Name;
                    userAccount = UserAccountAppService.GetSingleBySearch(userAccountSearch);
                    if (userAccount.IsNull())
                    {
                        userAccount = HttpContext.Current.Session()[GetType().FullName + "AuthUserAccount"] as UserAccount;
                        // is cached in session authentiated
                        if (userAccount.IsNull())
                        {
                            userAccount = UserAccountFactory.CreateUserAccount(Identity.Name);
                            HttpContext.Current.Session()[GetType().FullName + "AuthUserAccount"] = userAccount;
                            // keep it until end of the request
                        }
                    }
                    HttpContext.Current.Items[GetType().FullName + "UserAccount"] = userAccount; // keep it until end of the request
                }
                return userAccount;
            }
            else
            {
                var userAccount = HttpContext.Current.Session()[GetType().FullName + "UserAccount"] as UserAccount;
                // is cached for this request
                if (userAccount.IsNull())
                {
                    userAccount = UserAccountFactory.CreateUserAccount(Viewer);
                    userAccount.Roles = new List<Role>();
                    Role r = new Role(Mulala.Cavan.Domain.MainBoundedContext.SecurityModule.SecurityIdentifier.Role.Viewer.GetHashCode(),true);
                    userAccount.Roles.Add(r);

                    HttpContext.Current.Session()[GetType().FullName + "UserAccount"] = userAccount;
                    // keep it until end of the request
                }
                return userAccount;
            }

        }
        #endregion protected User

        #region protected properties
        protected virtual IIdentity Identity
        {
            get { return Thread.CurrentPrincipal.Identity; }
        }
        #endregion protected properties

        #region IoC
        IUserAccountAppService UserAccountAppService { get; set; }

        void Init()
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
            this.UserAccountAppService = ctx.GetObject("UserAccountAppService") as IUserAccountAppService;
            IList<AppMessage> lstMessage = new List<AppMessage>();
            UserAccountAppService.Messages = lstMessage;
        }
        #endregion IoC
    }
}